#include "cppfeaturestests/TestCppFeatures.h"

#include<numeric>

#include<iostream>

#include<boost/bind.hpp>

#include "boosttestsupport.h"
#include "accumulsupport/AccumulSupport.h"

#include "graphsupport/graph/BiGraph.h"

using namespace accumf;

int mmax( int a, int b )
{
	return a > b ? a : b;
}

void TestTrivialAccumulate()
{
	int src[] = { 1, 2, 10, 3, 4, 5 };
	int n = sizeof( src ) / sizeof( int );

	int product = std::accumulate( src, src + n, 1, std::multiplies< int >() );
	BOOST_CHECK_EQUAL( 1200, product );

	int last = std::accumulate( src, src + n, 1, boost::bind( std::plus< int >(), _2, 0 ) );
	BOOST_CHECK_EQUAL( 5, last );

	int max = std::accumulate( src, src + n, -1, mmax );
	BOOST_CHECK_EQUAL( 10, max );

	int count = 0;
	std::accumulate( src, src + n, -1, boost::bind( accumf::inc< int >, & count ) );
	BOOST_CHECK_EQUAL( 6, count );
}

void TestIfThnEls()
{
	int src[] = { 1, 2, 10, 3, 4, 5 };
	int n = sizeof( src ) / sizeof( int );
	int counter = 0;
	std::for_each(
		src,
		src + n,
		iftefnc(
			boost::bind( std::greater< int >(), _1, 3 ),
			boost::bind( accumf::inc< int >, & counter ),
			std::negate< int >() // NOP
		)
	);
	BOOST_CHECK_EQUAL( 3, counter );
}

void TestVecToString()
{
#ifdef os_windows
	IGNORE( "TestVecToString was ignored for windows" );
#endif
	int src[] = { 12, 34, 567, 890 };
	int n = sizeof( src ) / sizeof( int );
	std::vector< int > vec( n );

	std::copy( src, src+5, vec.begin() );

	BOOST_CHECK_EQUAL( "12, 34, 567, 890", COLL_TO_STRING( vec ) );

	BOOST_CHECK_EQUAL(
		std::string( "12, 34, 567, 890" ),
		iteraccumulate( src, src + n, std::string(), ToStringAccumulator( src + n ) )
	);

	std::vector< std::string > names;
	names.push_back( "abc" );
	names.push_back( "123" );
	names.push_back( "pamparam" );
	BOOST_CHECK_EQUAL(
		std::string( "abc, 123, pamparam" ),
		COLL_TO_STRING( names )
	);
}

void TestRTTI()
{
	BiGraph * testBiGrPtr = 0;
	BOOST_CHECK_EQUAL( ( BiGraph * )0, testBiGrPtr );

	BiGraph bg( 10, 20 );
	Graph & gr1 = bg;
	testBiGrPtr = dynamic_cast< BiGraph * >( & gr1 );
	BOOST_CHECK( testBiGrPtr != 0 );

	Graph graph( 30 );
	Graph & gr2 = graph;
	testBiGrPtr = dynamic_cast< BiGraph * >( & gr2 );
	BOOST_CHECK( testBiGrPtr == 0 );
}
